In [1]:
# imports
import os, sys
import binascii
# Configuration
rupd_file = "./user.hib" # path to file
out_path = './out/' # file output destination foder
out_file_stream = 'stream.txt' # data as hex strings in chunk per line
out_file_checks = 'checksum.txt' # checksum live generated
write_file = True # enable output files
chunksize = 2 # number of bytes to read from file per chunk
In [2]:
def to_hex_ascii(chunk):
"""
returns a hex ascii string representing the chunk.
:param chunk: data chunk
:return: -
"""
# Given raw bytes, get an ASCII string representing the hex values
hex_data = binascii.hexlify(chunk) # Two bytes values 0 and 255
# The resulting value will be an ASCII string but it will be a bytes type
# It may be necessary to decode it to a regular string
text_string = hex_data.decode('utf-8') # Result is string "00ff"
#print(text_string)
return text_string
def write_line(data, filehandle):
"""
Just another line writer, prints and write to file if given
:param data: string to print
:param filehandle: file handle
:return:
"""
#print(print_data)
if filehandle is not None and write_file:
filehandle.write(data + '\n')
def chunks_from_file(filename, chunksize=8192):
"""
reads binary chunks from a file and generates an iterator
:param filename:
:param chunksize:
:return:
"""
with open(filename, "rb") as f:
while True:
chunk = f.read(chunksize)
if chunk:
yield chunk
"""for b in chunk:
yield b"""
else:
break
def read_n_print(chunksize):
"""
Read and print whole file in a structured way in to a file.
- Chunks as line seperated hex string
- Current checksum after chunk
:return:
"""
# create output dir
if not os.path.exists(out_path):
os.makedirs(out_path)
# read file in chunks
fh_stream = open(out_path + out_file_stream, 'w')
for chunk in chunks_from_file(rupd_file, chunksize):
chunk_str = to_hex_ascii(chunk)
write_line(chunk_str, fh_stream)
# read file in chunks
fh_cks = open(out_path + out_file_checks, 'w')
checks = 0
for chunk in chunks_from_file(rupd_file, 2):
chunk_int = int.from_bytes(chunk, byteorder='little')
checks += chunk_int
checks_limited = to_hex_ascii(checks.to_bytes(4, byteorder='big'))[-4:]
write_line("{} >> {}".format(hex(chunk_int), checks_limited), fh_cks)
checks = int.from_bytes(binascii.unhexlify(checks_limited), byteorder='big')
# close open files
if fh_stream is not None:
fh_stream.close()
if fh_cks is not None:
fh_cks.close()
# Program Code
# ===================================================
# File Read & Analyze
print("--- Start Remote Update file analysis --------------------------")
# Print remote update data in structured format
print(sys.version_info)
if sys.version_info[0] == 3:
read_n_print(chunksize)
else:
print("Python 3 is needed!")
print("--- End --------------------------------------------------------")